package jmine.tec.extensions.impl.forms.server;

import java.util.Collection;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import jmine.tec.extensions.TecExtensionsException;
import jmine.tec.extensions.forms.FormHandler;
import jmine.tec.extensions.impl.TecExtensionsMessages;
import jmine.tec.utils.register.Receiver;

/**
 * @author wagner.tsuchiya
 */
public class ServerSideRegisteredFormHandler implements Receiver<FormHandler<?>>, FormHandler<Object> {

    private Map<Class<?>, FormHandler<?>> handlers = new HashMap<Class<?>, FormHandler<?>>();

    /**
     * {@inheritDoc}
     */
    public List<String> validate(Object form) {
        return this.getFormHandler(form).validate(form);
    }

    /**
     * {@inheritDoc}
     */
    public void apply(Object form) {
        this.getFormHandler(form).apply(form);
    }

    /**
     * {@inheritDoc}
     */
    public Class<Object> formClass() {
        return Object.class;
    }

    /**
     * @param <F> the form type.
     * @param object object.
     * @return the form handler.
     */
    @SuppressWarnings("unchecked")
    private <F> FormHandler<F> getFormHandler(F object) {
        if (this.handlers.containsKey(object.getClass())) {
            throw new TecExtensionsException(TecExtensionsMessages.HANDLER_NOT_FOUND_FOR_CLASS.create(object.getClass()));
        }
        FormHandler<?> delegate = this.handlers.get(object.getClass());
        if (!delegate.formClass().isInstance(object)) {
            throw new TecExtensionsException(TecExtensionsMessages.INCOMPATIBLE_TYPE_FOR_HANDLER.create(object.getClass()));
        }
        return (FormHandler<F>) delegate;
    }

    /**
     * {@inheritDoc}
     */
    public void register(Collection<? extends FormHandler<?>> registers) {
        for (FormHandler<?> formHandler : registers) {
            this.handlers.put(formHandler.formClass(), formHandler);
        }
    }
}
